/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package generatorGraphics.graphics;

import grammaticalClasses.nwConsole.ShowMote;
import java.awt.Color;
import java.awt.Dimension;
import java.text.NumberFormat;
import java.util.ArrayList;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.StackedBarRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import softwareControl.SearchCommands;

/**
 *
 * @author Heitor
 */
public class MoteBandwidth implements GraphInterface{
    
    /**
     * Variável que executa as classes gramaticais.
     */ 
    private SearchCommands search;
    
    /**
     * Titulo do tipo de gráfico
     */
    private String name;
    /**
     * Descrição do gráfico - HELP
     */
    private String help;
        
    /** Armazena o gráfico que será colhido pela tela pai */
    private ChartPanel chartPanel;
    
    /**
     * Armazena um vetor/array de string referentes ao nome das unidades
     */
    private ArrayList<String> unitList;
    
    /**
     * Armazena todos os vetores/arrays de opções.
     * Cada vetor/array dentro de 'optionsList' tem seu primeiro elemento 
     * representando qual o nome/string da unidade a que as opções se refere.
     * -Exemplo: 
     * --Unidade: "Teste1"; Opções: "O1", "O2" e "O3";
     * --Unidade: "Teste2"; Opções: "O4", "O5" e "O6";
     * --- unitList: ["Teste1", "Teste2"];
     * --- optionsList: [["[UNIT]Teste1", "O1", "O2", "O3"], ["[UNIT]Teste2", "O4", "O5", "O6"]];
     */
    private ArrayList<ArrayList<String>> optionsList;
    
    /** 
     * Armazena qual unidade está ativada/selecionada
     * - Por 'default' a primeira de toda lista se torna selecionada
     */
    private String unitActive;
    
    /** 
     * Construtor 
     */
    public MoteBandwidth(){
        
        unitList = new ArrayList<>();
        optionsList = new ArrayList<>();
        
        name = "Mote Bandwidth";
        help = "Help of Mote Bandwidth";
        
        configUnitOptions();
        
        createGraph("");
    }
    
    /**
     * Configura todos os campos de unidades e de opções.
     * Realizando a ligação entre unidades e seus respectivos vetores de opções.
     */
    private void configUnitOptions(){
        
        // Adicionando as unidades
        unitList.add("General");
        unitList.add("Per parents");
        
        //Adicionando as opções
        for (int i=0; i<unitList.size(); i++){
            ArrayList<String> aux = new ArrayList<>();
            switch (unitList.get(i)) {
                case "General":
                    aux.add("[UNIT]" + unitList.get(i));
                    aux.add("No Sort");
                    aux.add("Sort by Services");
                    aux.add("Sort by Child");
                    aux.add("Sort by Free");
                    optionsList.add(aux);
                    break;
                case "Per parents":
                    aux.add("[UNIT]" + unitList.get(i));
                    aux.add("All");
                    aux.add("Connected to Gateway");
                    aux.add("No connected to Gateway");
                    optionsList.add(aux);
                    break;
            }
        }
        
    }

    /**
     * Cria o gráfico referente a 'unit'
     * @param unit 
     */
    private void createGraph(String unit) {
        
        ArrayList<Object> answer;
        ArrayList<String> commands = new ArrayList<>();
        
        switch (unit){
            case "General":
                commands.add("ShowMote");

                search = new SearchCommands(commands);
                answer = (ArrayList<Object>) search.getCommandsAnswer();
                
                chartPanel = new ChartPanel(buildGraphGeneral((ArrayList<ShowMote>) answer.get(0)));
                chartPanel.setBackground(Color.LIGHT_GRAY);
                chartPanel.setPreferredSize(new Dimension(700, 350)); 
                chartPanel.setDomainZoomable(false);
                chartPanel.setRangeZoomable(false);

                break;
            case "Per parents":
                commands.add("ShowMote");

                search = new SearchCommands(commands);
                answer = (ArrayList<Object>) search.getCommandsAnswer();

                chartPanel = new ChartPanel(buildGraphParents((ArrayList<ShowMote>) answer.get(0)));
                chartPanel.setBackground(Color.LIGHT_GRAY);
                chartPanel.setPreferredSize(new Dimension(700, 350)); 
                chartPanel.setDomainZoomable(false);
                chartPanel.setRangeZoomable(false);

                break;
                
            default:
                chartPanel = new ChartPanel(null);
                
                break;
        }
    }    
    
    /**
     * Verifica se o 'texto' é um número. Podendo ser inteiro ou float.
     * @param texto
     * @return 
     */
    public static boolean isNumber(String texto) {  
        if(texto == null || texto.equals("")) {
            return false;
        }  
        for (char letra : texto.toCharArray()) {
            if((letra < '0' || letra > '9') && (letra != '.')) {
                return false;
            }
        }  
        return true;  
        
    }
    
    private JFreeChart buildGraphGeneral(ArrayList<ShowMote> auxMote){
        
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for(int i=0; i<auxMote.size(); i++){

            if((!(auxMote.get(i).getMoteType().equals(" AP"))) && 
                    (!(auxMote.get(i).getMoteType().equals("AP"))) && 
                    (!(auxMote.get(i).getMoteType().equals("Ap")))){
                if(isNumber(auxMote.get(i).getBandServ())){
                    dataset.addValue(Double.valueOf(auxMote.get(i).getBandServ()), "Services", auxMote.get(i).getIdMote());
                }
                if(isNumber(auxMote.get(i).getBandChild())){
                    dataset.addValue(Double.valueOf(auxMote.get(i).getBandChild()), "Child", auxMote.get(i).getIdMote());
                }
                if(isNumber(auxMote.get(i).getBandFree())){
                    dataset.addValue(Double.valueOf(auxMote.get(i).getBandFree()), "Free", auxMote.get(i).getIdMote());
                }
            }
        }

        JFreeChart chart0 = ChartFactory.createStackedBarChart(name,
                "Devices", 
                "Value", 
                dataset, 
                PlotOrientation.VERTICAL, 
                true, true, true);
        chart0.setBackgroundPaint(new Color(238, 238, 238));
        //System.out.println("Olha: " + chart0.getBackgroundPaint());

        CategoryPlot categoryplot = (CategoryPlot) chart0.getPlot();
        NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis();
        numberaxis.setNumberFormatOverride(NumberFormat.getPercentInstance());
        StackedBarRenderer stackedbarrenderer = (StackedBarRenderer)categoryplot.getRenderer();
        stackedbarrenderer.setDrawBarOutline(false);
        stackedbarrenderer.setBaseItemLabelsVisible(true);
        stackedbarrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        
        return chart0;
        
    }
    
    private JFreeChart buildGraphParents(ArrayList<ShowMote> auxMote2){
    
        DefaultCategoryDataset dataset2 = new DefaultCategoryDataset();
        for(int i=0; i<auxMote2.size(); i++){
            for(int j=0; j<auxMote2.get(i).getBandIdParentList().size(); j++){
                if(isNumber(auxMote2.get(i).getBandParentList().get(j))){

                    if(Double.valueOf(auxMote2.get(i).getBandParentList().get(j)) != 0){
                        dataset2.addValue(Double.valueOf(auxMote2.get(i).getBandParentList().get(j)), 
                            auxMote2.get(i).getBandIdParentList().get(j), 
                            auxMote2.get(i).getIdMote());
                    }
                }
            }
        }

        JFreeChart chart2 = ChartFactory.createBarChart(name, 
                "Devices",
                "Value",
                dataset2,
                PlotOrientation.VERTICAL,
                true,
                true,
                false);
        //chart2.setBackgroundPaint(Color.GRAY);

        CategoryPlot plot2 = (CategoryPlot) chart2.getPlot();
        plot2.setBackgroundPaint(Color.white);
        plot2.setDomainGridlinePaint(Color.BLACK);
        plot2.setDomainGridlinesVisible(true);
        plot2.setRangeGridlinePaint(Color.LIGHT_GRAY);
        
        return chart2;
    
    }
    
    @Override
    public String toString(){
        return name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public ArrayList<String> getUnitList() {
        return unitList;
    }

    /**
     * Retorna o chartPanel 'default'
     * @return 
     */
    @Override
    public ChartPanel getChartPanel() {
        return chartPanel;
    }

    @Override
    public String getHelp() {
        return help;
    }

    @Override
    public ChartPanel getChartPanel(String unit) {
        for(int i=0; i<unitList.size(); i++){
            if(unit.equals(unitList.get(i))){
                createGraph(unit);
            }
        }
        return chartPanel;
    }

    @Override
    public ArrayList<String> getOptionsList(String unit) {
        ArrayList<String> auxReturn = new ArrayList<>();
        
        for(int i=0; i<optionsList.size(); i++){
            if((optionsList.get(i)).get(0).equals("[UNIT]" + unit)){
                
                for(int j=1; j<optionsList.get(i).size(); j++){
                    auxReturn.add(optionsList.get(i).get(j));
                }
            }
        }
        return auxReturn;
    }
    
}
